package model

import (
	"fmt"

	"github.com/google/uuid"
	"gorm.io/gorm"
)

type Ticket struct {
	ID       string         `json:"id"`
	Title    string         `json:"title"`
	Message  string         `json:"message" gorm:"type:LONGTEXT"`
	Priority TicketPriority `json:"priority"`
	Type     string         `json:"type"`
	ClientID string         `json:"client_id"`
	UserID   string         `json:"user_id"`
	Status   TicketStatus   `json:"status"`

	// AppendixPath is the result of url.Values.Encode().
	// You can use url.ParseQuery and key(files) receive all appendix paths.
	AppendixPath string `json:"appendix_path"`
}

type TicketPriority string

const (
	TicketPriorityLow       TicketPriority = "low"
	TicketPriorityCommon    TicketPriority = "common"
	TicketPriorityCrash     TicketPriority = "crash"
	TicketPriorityVeryCrash TicketPriority = "very_crash"
)

func IsSpecifiedPriority(priority string) (TicketPriority, bool) {
	tp := TicketPriority(priority)
	switch tp {
	case TicketPriorityLow:
		return TicketPriorityLow, true
	case TicketPriorityCommon:
		return TicketPriorityCommon, true
	case TicketPriorityCrash:
		return TicketPriorityCrash, true
	case TicketPriorityVeryCrash:
		return TicketPriorityVeryCrash, true
	default:
		return "", false
	}
}

type TicketStatus string

const (
	TicketStatusPendding   TicketStatus = "pending"
	TicketStatusFinish     TicketStatus = "finish"
	TicketStatusProcessing TicketStatus = "processing"
)

func CreateTicket(db *gorm.DB, ticket *Ticket) error {
	if ticket.ID == "" {
		ticket.ID = uuid.NewString()
	}
	ticket.Status = TicketStatusPendding
	if ticket.UserID == "" {
		return fmt.Errorf("create ticket failed: missing user id")
	}
	return db.Create(ticket).Error
}

func DeleteTicket(db *gorm.DB, id string) error {
	return db.Delete(&Ticket{ID: id}).Error
}

func UpdateTicket(db *gorm.DB, ticket *Ticket) error {
	return db.Model(&Ticket{ID: ticket.ID}).Updates(ticket).Error
}

func FindTicket(db *gorm.DB, id string) (*Ticket, error) {
	ticket := &Ticket{}
	err := db.Where("id = ?", id).First(&ticket).Error
	return ticket, err
}

func ListTickets(db *gorm.DB, filters map[string]interface{}) ([]Ticket, error) {
	tt := []Ticket{}
	err := db.Where(filters).Find(&tt).Error
	return tt, err
}

func ListTicketsByClientID(db *gorm.DB, clientID string) ([]Ticket, error) {
	tt := []Ticket{}
	err := db.Where("client_id = ?", clientID).Find(&tt).Error
	return tt, err
}

func ListTicketsByUserID(db *gorm.DB, userID string) ([]Ticket, error) {
	tt := []Ticket{}
	err := db.Where("user_id = ?", userID).Find(&tt).Error
	return tt, err
}
